﻿using System.Collections.Generic;
using System.Xml;
using BlogsAPI.Interfaces;
using Newtonsoft.Json.Linq;

namespace BlogsAPI.Sites
{
    using System.Web;
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using Abstract;

    /// <summary>
    /// Videohost - Vimeo.com
    /// </summary>
    [BlogServiceAPI(Description = "Vimeo", Link = "http://vimeo.com")]
    public class Vimeo : BlogServer, IVideoHost
    {
        private static readonly Regex Validation = new Regex(@"^https?://(?:[-_\w]+\.)?vimeo\.com", Regexoptions);
        
        private static readonly Regex statsNumber = new Regex(@"<stats_number_of_plays>(\d+)<", Regexoptions);
        private static readonly Regex uploadDate = new Regex(@"<upload_date>([^>]+)<", Regexoptions);
        private static readonly Regex Title = new Regex(@"<title>([^>]+)<", Regexoptions);


        #region interface: BlogServer

        [DebuggerStepThrough]
        public Vimeo()
        {
            Encoding = Encoding.UTF8;
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(String sLink)
        {
            return Validation.Match(sLink).Success;
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        /// <param name="sLink">ссылка для проверки</param>
        /// <param name="userName">Имя пользователя на блогохостинге</param>
        /// <param name="bType">Тип блога - пользователь или сообщество</param>
        public override Boolean ValidateLink(String sLink, out String userName, out BlogType bType)
        {
            bType = BlogType.Unknown;
            userName = String.Empty;
            if (String.IsNullOrEmpty(sLink)) return false;
            Match m = Regex.Match(sLink, @"\D(\d+)(?:\b|$)", Regexoptions);
            if(m.Success)
            {
                userName = m.Groups[1].Value;
            }
            return ValidateLink(sLink);
        }

        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - пользователь или сообщество</param>
        public override String GetBlogLink(string userName, BlogType btype)
        {
            //https://vimeo.com/user13779008
            return String.Format("https://vimeo.com/user{0}", userName);
        }

        /// <summary>
        /// Извлечение картинки пользователя
        /// </summary>
        /// <param name="userName">имя блогера</param>
        /// <param name="btype">тип блога</param>
        /// <returns>Прямая ссылка на картинку</returns>
        public override string ExtractAvatar(string userName, BlogType btype)
        {
            try
            {
                //http://vimeo.com/api/v2/8766782/info.xml
                var resp = 
                    (HttpWebResponse)Common.MakeRequest(String.Format("http://vimeo.com/api/v2/{0}/info.json", userName)).GetResponse();
                string json = new StreamReader(resp.GetResponseStream()).ReadToEnd();
                JObject obj = JObject.Parse(json);
                return obj["portrait_medium"].Value<string>();
            }
            catch (Exception e1)
            {
                Debug.WriteLine("Ошибка получения:" + e1.Message);
            }
            return String.Empty;
        }

        #endregion

        #region IVideoHost

        /// <summary>
        /// просто ссылки на видео
        /// </summary>
        public static readonly Regex rVimeoVideo = new Regex(@"vimeo.com\W(?:.*?clip_id\W)?(\d+)(\D|$)", Regexoptions);

        private static readonly Regex rThumbnail2 = new Regex(@"<thumbnail_medium>([^<]+)<", Regexoptions);

        /// <summary>
        /// Получение данных по ссылке
        /// </summary>
        /// <param name="link"></param>
        /// <returns></returns>
        public Tuple<VideoData, BlogPost> GetVideoData(Uri link)
        {
            var oRet = new Tuple<VideoData, BlogPost>(
                new VideoData(link),
                new BlogPost(link) { Existance = false,Links = 0,Comments = 0});
            try
            {
                Match v = rVimeoVideo.Match(link.OriginalString);
                if (v.Success)
                {
                    Uri postlink;
                    if (Uri.TryCreate(String.Format("http://vimeo.com/api/v2/video/{0}.xml", v.Groups[1].Value),
                                      UriKind.Absolute, out postlink))
                    {
                        var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(postlink);
                        myHttpWebRequest.AllowAutoRedirect = false;
                        var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                        if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
                        {
                            string reply = new StreamReader(myHttpWebResponse.GetResponseStream()).ReadToEnd();
                            Match img = rThumbnail2.Match(reply);
                            if (img.Success)
                            {
                                oRet.Item1.Replace = "<a href=\"" +
                                          link.OriginalString + "\"><img src=\"" + img.Groups[1].Value +
                                          "\"/>[Видео]</a>";
                                oRet.Item1.Images += "<img src=\"" + img.Groups[1].Value + "\"/>";
                            }
                            //а теперь просмотры!
                            Match vs = statsNumber.Match(reply);
                            if (vs.Success)
                            {
                                oRet.Item1.Views += int.Parse(vs.Groups[1].Value);
                            }
                            Match pDate = uploadDate.Match(reply);
                            if (!pDate.Success || !DateTime.TryParse(pDate.Groups[1].Value.Trim().Replace(" ", "T"),
                                out oRet.Item1.Published))
                            {
                                oRet.Item1.Published = DateTime.Now.AddMonths(-1);//чтобы не вставить текущий день
                            }
                            //формирование поста...
                            Match title = Title.Match(reply);
                            if (title.Success)// && Common.IsRussian(title.Groups[1].Value))
                            {
                                try
                                {
                                    var xDoc = new XmlDocument();
                                    xDoc.LoadXml(reply);
                                    var selectSingleNode = xDoc.SelectSingleNode("//duration");
                                    if (selectSingleNode != null)
                                        oRet.Item1.Duration = Math.Max(oRet.Item1.Duration,
                                                            uint.Parse(selectSingleNode.InnerText));
                                    oRet.Item2.Existance = true;
                                    oRet.Item2.Published = oRet.Item1.Published;
                                    oRet.Item2.Views = oRet.Item1.Views;
                                    oRet.Item2.Links = 0;
                                    oRet.Item2.Comments =
                                        int.Parse(
                                            xDoc.SelectSingleNode("//stats_number_of_comments").InnerText.
                                                 Trim()); //stats_number_of_comments
                                    oRet.Item2.Body = xDoc.SelectSingleNode("//description").InnerText;
                                    oRet.Item1.About = oRet.Item2.Body;
                                    oRet.Item2.SpecialParam = xDoc.SelectSingleNode("//user_id").InnerText;
                                    //////////////
                                    oRet.Item2.Subject = xDoc.SelectSingleNode("//user_name").InnerText + ": " +
                                                         title.Groups[1].Value.Trim().Replace("логгер", "логер");
                                    oRet.Item1.Title = oRet.Item2.Subject;
                                    //////////////
                                    
                                    oRet.Item2.Attributes = new PostAttributeCollection
                                        {
                                            new PostAttribute(PostParams.Tags,
                                                              xDoc.SelectSingleNode("//tags").InnerText),
                                            new PostAttribute(PostParams.MediaThumbnail,
                                                              xDoc.SelectSingleNode("//thumbnail_medium").
                                                                   InnerText),
                                            new PostAttribute(PostParams.Length, oRet.Item1.Duration)
                                        };
                                }
                                catch (Exception e1)
                                {
                                    Debug.WriteLine(e1.Message);
                                }
                            }
                            
                        }
                        myHttpWebResponse.Close();
                    }
                }
            }
            catch (Exception e1)
            {
                Debug.Write(e1);
            }
            return oRet;
        }

        /// <summary>
        /// Код для размещения на сторонних ресурсах
        /// </summary>
        /// <param name="link"></param>
        /// <returns></returns>
        public string FormEmbedCode(Uri link, String adds = null)
        {
            string username;
            BlogType bt;
            if (ValidateLink(link.OriginalString,out username,out bt))
            {
                return String.Format(
                    "<iframe src=\"http://player.vimeo.com/video/{0}?title=0&amp;byline=0&amp;portrait=0\" width=\"620\" height=\"349\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>",username);
            }
            return String.Empty;
        }

        #endregion

        /// <summary>
        /// Убираем параметры
        /// </summary>
        /// <param name="videolink"></param>
        /// <returns></returns>
        public override string ToCanonicalLink(string videolink)
        {
            return base.ToCanonicalLink(videolink).Replace("http://","https://");//только по https теперь
        }
    }
}